package com.jwgf.smarowindingmachine_unity.logic;

import com.alibaba.fastjson.JSON;
import com.jwgf.Half485.modbusthreadpool.ModbusCommandManager;
import com.jwgf.fram.FramInterface;
import com.jwgf.group.Group;
import com.jwgf.group.GroupMap;
import com.jwgf.objectbox.CbfFaultRecord;
import com.jwgf.objectbox.CbfFaultRecord_;
import com.jwgf.objectbox.CbfReport;
import com.jwgf.objectbox.CbfReport_;
import com.jwgf.objectbox.DofferFaultRecord;
import com.jwgf.objectbox.DofferFaultRecord_;
import com.jwgf.objectbox.FaultCounter;
import com.jwgf.objectbox.FaultCounter_;
import com.jwgf.objectbox.FaultRecord;
import com.jwgf.objectbox.FaultRecord_;
import com.jwgf.objectbox.GroupInfo;
import com.jwgf.objectbox.GroupInfo_;
import com.jwgf.objectbox.HeadFaultRecord;
import com.jwgf.objectbox.HeadFaultRecord_;
import com.jwgf.objectbox.HeadReport;
import com.jwgf.objectbox.ObjectBox;
import com.jwgf.objectbox.ProcessCounter;
import com.jwgf.objectbox.ProcessCounter_;
import com.jwgf.objectbox.ProcessRecord;
import com.jwgf.objectbox.ProcessRecord_;
import com.jwgf.objectbox.RedLightCounter;
import com.jwgf.objectbox.RedLightCounter_;
import com.jwgf.objectbox.RedLightRecord;
import com.jwgf.objectbox.RedLightRecord_;
import com.jwgf.objectbox.ShiftReport;
import com.jwgf.objectbox.ShiftReport_;
import com.jwgf.objectbox.SpindleParameter;
import com.jwgf.objectbox.SpindleRecord;
import com.jwgf.objectbox.SpindleRecord_;
import com.jwgf.objectbox.StatisticRecord;
import com.jwgf.objectbox.StatisticRecord_;
import com.jwgf.objectbox.TubeRecord;
import com.jwgf.objectbox.TubeRecord4E;
import com.jwgf.objectbox.TubeRecord4E_;
import com.jwgf.objectbox.TubeRecord_;
import com.jwgf.report.ShiftChangeOperations;
import com.jwgf.report.ShiftTimeRule;
import com.jwgf.smarowindingmachine_unity.ui.SmaroWindingMachineActivity;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import io.objectbox.Box;

public class ShiftChangeOperator implements ShiftChangeOperations {

    @Override
    public void doShiftChange() {
        saveHeadReport();
        saveGroupInfo();
        saveProductionData();
        saveStatisticData();

        Box<RedLightCounter> redLightCounterBox = ObjectBox.get().boxFor(RedLightCounter.class);
        redLightCounterBox.put(Report.getInstance().getTailRedLightCounter());

        Box<ProcessCounter> processCounterBox = ObjectBox.get().boxFor(ProcessCounter.class);
        processCounterBox.put(Report.getInstance().getTailProcessCounter());

        Box<FaultCounter> faultCounterBox = ObjectBox.get().boxFor(FaultCounter.class);
        faultCounterBox.put(Report.getInstance().getTailFaultCounter());

        // clear to zero
        Report.getInstance().clearAllReportAuto();
        // save cbf_doffer data to db
        // 大纱库：5号栈
        Box<CbfReport> box = ObjectBox.get().boxFor(CbfReport.class);
        box.put(Report.getInstance().getTailCBFDoffer());

        // clear zero
        Report.getInstance().clearParaToZero();

        // send clear zero cmd to plc
        byte[] datai = new byte[2];
        datai[0] = 0;
        datai[1] = 1;
        ModbusCommandManager.getInstance().putPriorityCmd(CommandGenerator.createWriteCommand((byte) 1, 64, datai));
        ModbusCommandManager.getInstance().putPriorityCmd(CommandGenerator.createWriteCommand((byte) 1, 102, datai));
        SmaroWindingMachineActivity.canHandStack.putPriorityCmd(
                MachineParameterSharedPreference.getInstance().createCanCmd75(0x75, 0x01, 514, "1"));


        FramInterface.getInstance().writeFile();
        clearLastMonthData();
    }

    private void saveHeadReport() {
        Box<HeadReport> box = ObjectBox.get().boxFor(HeadReport.class);
        box.put(Report.getInstance().getTailHeadReport());
    }

    private void saveGroupInfo() {
        Box<GroupInfo> box = ObjectBox.get().boxFor(GroupInfo.class);
        GroupInfo info = new GroupInfo();
        info.start = Long.valueOf(ShiftTimeRule.getInstance().getCurrentShiftStartTime());
        List<Group> groups = GroupMap.getInstance().getGroupList();
        info.groupInfo = JSON.toJSONString(groups);
        List<SpindleParameter> parameters = new ArrayList<>();
        for (Group group: groups) {
            long id = group.getId();
            SpindleParameter parameter = ObjectBox.get().boxFor(SpindleParameter.class).get(id);
            parameters.add(parameter);
        }
        info.spindleParameters = JSON.toJSONString(parameters);
        box.put(info);
    }

    private void saveProductionData() {
        Box<ShiftReport> box = ObjectBox.get().boxFor(ShiftReport.class);

        //sum
        ShiftReport sumProduction = Report.getInstance().getTailSumProduction();
        //avg
        ShiftReport avgProduction = Report.getInstance().getTailAvgProduction();
        //group
        List<ShiftReport> groupProduction = Report.getInstance().getTailGroupProduction();
        //spindle
        List<ShiftReport> spindleProduction = Report.getInstance().getTailSpindleProduction();

        List<ShiftReport> productionList = new ArrayList<>();
        productionList.add(sumProduction);
        productionList.add(avgProduction);
        productionList.addAll(groupProduction);
        productionList.addAll(spindleProduction);
        box.put(productionList);
    }

    private void saveStatisticData() {
        Box<StatisticRecord> box = ObjectBox.get().boxFor(StatisticRecord.class);
        StatisticRecord sum = Report.getInstance().getTailSumStatistic();
        StatisticRecord avg = Report.getInstance().getTailAvgStatistic();
        List<StatisticRecord> group = Report.getInstance().getTailGroupStatistic();
        List<StatisticRecord> spindle = Report.getInstance().getTailSpindleStatistic();
        List<StatisticRecord> list = new ArrayList<>();
        list.add(sum);
        list.add(avg);
        list.addAll(group);
        list.addAll(spindle);
        box.put(list);
    }

    public void clearLastMonthData() {
        long curTime = Long.valueOf(ShiftTimeRule.getInstance().getCurrentShiftStartTime());
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(curTime);
        c.add(Calendar.DAY_OF_MONTH, -4);
        long thirtyDaysAgo = c.getTimeInMillis();

        ObjectBox.get().boxFor(GroupInfo.class).query().less(GroupInfo_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(ShiftReport.class).query().less(ShiftReport_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(CbfReport.class).query().less(CbfReport_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(RedLightRecord.class).query().less(RedLightRecord_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(ProcessRecord.class).query().less(ProcessRecord_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(FaultRecord.class).query().less(FaultRecord_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(StatisticRecord.class).query().less(StatisticRecord_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(HeadFaultRecord.class).query().less(HeadFaultRecord_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(CbfFaultRecord.class).query().less(CbfFaultRecord_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(DofferFaultRecord.class).query().less(DofferFaultRecord_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(TubeRecord.class).query().less(TubeRecord_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(TubeRecord4E.class).query().less(TubeRecord4E_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(FaultCounter.class).query().less(FaultCounter_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(ProcessCounter.class).query().less(ProcessCounter_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(RedLightCounter.class).query().less(RedLightCounter_.start, thirtyDaysAgo).build().remove();
        ObjectBox.get().boxFor(SpindleRecord.class).query().less(SpindleRecord_.start, thirtyDaysAgo).build().remove();
    }
}
